﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GACFFP.Models
{
    public class GACFFP_Repository
    {

        GACFFP.FootballPollEntities fpE = new FootballPollEntities();

        /// <summary>
        /// Get user object by user id
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public GACFFP.User GetUser(int UserID)
        {
            try
            {
                GACFFP.User thisUser = (from User in fpE.Users
                                        where User.id == UserID
                                        select User).FirstOrDefault();

                return thisUser;
            }
            catch (Exception e)
            {
                //TODO logging logic
                return null;
            }
        }


        public bool UpdateUser(GACFFP.User thisUser)
        {
            try
            {
                var updateThisUser = (from Users in fpE.Users
                                      where Users.id == thisUser.id
                                      select Users).Single();

                // Change the name of the contact.
                updateThisUser.userName = thisUser.userName;
                updateThisUser.role = thisUser.role;

                fpE.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                //TODO logging logic
                return false;
            }
        }

        public int GetUserID() 
        {
            string UserName = HttpContext.Current.Request.Cookies["GACFFP_Voter"].ToString();
            return GetUserID(UserName);
        }

      

        public int GetUserID(string UserName)
        {
            try
            {
                int UserId = (from Users in fpE.Users
                              where Users.userName == UserName
                              select Users.id).First();

                return UserId;
            }
            catch (Exception e)
            { 
                //TODO logging Logic
                return -1;
            }
        
        }



        public IList<User> GetUserLIst()
        {
          
            return fpE.Users.ToList();

        }
       









        /// <summary>
        /// This method calls the stored procedure GetCurrentTeamRankedByPoints.
        /// it returns the list of teams by their total points by date range.
        /// So in theory over time you can get an aggregated ranking.
        /// </summary>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public IList<RankedTeams> GetCurrentPoll(DateTime startDate, DateTime endDate)
        {
           
           
           return  fpE.GetCurrentTeamRankedByPoints(startDate, endDate).ToList();

        }

        /// <summary>
        /// overload with no date set.  Gets the poll for this week.
        /// </summary>
        /// <returns></returns>
        public IList<RankedTeams> GetCurrentPoll()
        {
            //Get Sunday
            DateTime startDate = Services.PeriodValidator.GetThisWeekStart();
            //Get Saturday
            DateTime endDate = Services.PeriodValidator.GetThisWeekEnd();

            //call the overload
            //return team
            return GetCurrentPoll(startDate, endDate);
        }


        /// <summary>
        /// Gets the raw list of teams ordered by team name
        /// used primarily in the select from page element.
        /// </summary>
        /// <returns></returns>
        public IQueryable<Team> FindAllTeams()
        {
            try
            {
                return fpE.Teams.OrderBy(t => t.teamName);
            }
            catch(Exception e)
            {
                //TODO logging logic
                return null;
            }
        }
        

        /// <summary>
        /// This method adds a users vote to the system
        /// it takes it as a set of votes for the top 25 teams
        /// and saves them row by row, team by team.
        /// </summary>
        /// <param name="thisVoteSet"></param>
        /// <returns></returns>
        public Boolean AddVote(List<GACFFP.Vote> thisVoteSet)
        {
            try
            {
                foreach (GACFFP.Vote v in thisVoteSet)
                {

                    fpE.AddToVotes(v);
                }

                fpE.SaveChanges();

                return true;

            }
            catch (Exception e)
            {
                //TODO logging logic
                return false;
            }
           
        }


        /// <summary>
        /// The voting is only open certains days of the week.
        /// this method returns the available open days to vote for the week.
        /// typically Sunday to Wednesday for college football voting 
        /// </summary>
        /// <param name="season"></param>
        /// <returns></returns>
        public string[] GetAllowedDaysToVote(int season)
        {
            
            string DaysSet = (from VotingPeriod in fpE.VotingPeriods
                                        where VotingPeriod.id==1
                                        select VotingPeriod.vDaysOpen).FirstOrDefault();

            char[] separator = new char[] { ',' };
            string[] DaysOpen = DaysSet.Split(separator);
          
            return DaysOpen;
        }


        public string[] GetAllowedDaysToVote()
        {
            return GetAllowedDaysToVote(1);

        }


        /// <summary>
        /// The season has a start and an end.
        /// This method returns the DateTime object for the start of the season.
        /// </summary>
        /// <param name="season"></param>
        /// <returns></returns>
        public DateTime GetStartOfSeason(int season)
        {
            DateTime seasonStart = (from VotingPeriod in fpE.VotingPeriods
                                    where VotingPeriod.id == season
                                    select VotingPeriod.vPeriodStart).FirstOrDefault();

            return seasonStart;
        }

        public DateTime GetStartOfSeason()
        {
            return GetStartOfSeason(1);
        }


        /// <summary>
        /// The season has a start and an end.
        /// This method returns the Datetime object for the end of the season.
        /// </summary>
        /// <param name="season"></param>
        /// <returns></returns>
        public DateTime GetEndOfSeason(int season)
        {
            DateTime seasonEnd = (from VotingPeriod in fpE.VotingPeriods
                                    where VotingPeriod.id == season
                                    select VotingPeriod.vPeriodEnd).FirstOrDefault();

            return seasonEnd;
        }

        public DateTime GetEndOfSeason()
        {
            return GetEndOfSeason(1);
        }


        /// <summary>
        /// Update Start of Season
        /// </summary>
        /// <returns></returns>
        public bool UpdateStartOfSeason(DateTime startDate)
        {
            return UpdateStartOfSeason(startDate, 1);
        }

        public bool UpdateStartOfSeason(DateTime startDate, int season)
        {
            try
            {
                //DateTime newStart = new DateTime(2011, 10, 7);


                var startUpdated = (from VotingPeriod in fpE.VotingPeriods
                                         where VotingPeriod.id == season
                                         select VotingPeriod).Single();

                // Change the name of the contact.
                startUpdated.vPeriodStart = startDate;

                fpE.SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                return false;
            }

        }


        /// <summary>
        /// Update End of Season
        /// </summary>
        /// <returns></returns>
        public bool UpdateEndOfSeason(DateTime endDate)
        {
            return UpdateEndOfSeason(endDate, 1);
        }

        public bool UpdateEndOfSeason(DateTime endDate, int season)
        {
            try
            {
                //DateTime newEnd = new DateTime(2011, 10, 7);


                var EndUpdated = (from VotingPeriod in fpE.VotingPeriods
                                  where VotingPeriod.id == season
                                  select VotingPeriod).Single();

                // Change the name of the contact.
                EndUpdated.vPeriodEnd = endDate;

                fpE.SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                return false;
            }

        }




        /// <summary>
        /// This method checks the available cookie and querystring and returns a user object
        /// </summary>
        /// <returns></returns>
        public GACFFP.User GetCurrentUser()
        {
           string sGACFFP_voterName = string.Empty;

            //check cookie
           try
           {
               if (HttpContext.Current.Request.Cookies["GACFFP_Voter"] != null && HttpContext.Current.Request.Cookies["GACFFP_Voter"].Value.Length>0)
               {
                   string sGACFFP_Raw = HttpContext.Current.Request.Cookies["GACFFP_Voter"].Value;
                   //string[] gv_cookieSplit =
                   sGACFFP_voterName = sGACFFP_Raw.Split('=')[1];

               }
           }
           catch (Exception e)
           {
               //TODO logging logic

           }

            //is it in a querystring?  takes precedent
            if (HttpContext.Current.Request.QueryString.Keys.Count > 0)
            {
                //check querystring
                if (HttpContext.Current.Request.QueryString["GACFFP_Voter"] != null)
                {
                    sGACFFP_voterName = HttpContext.Current.Request.QueryString["GACFFP_Voter"];

                    
                }

            }

            //if we set to guest
            if (sGACFFP_voterName.Length == 0)
            {
                 sGACFFP_voterName ="guest";
            }

            return GetCurrentUser(sGACFFP_voterName);


        }


        /// <summary>
        /// This method takes a string value as input and returns a user object
        /// it passes the default of true to the overloaded method for automatically setting the cookie.
        /// </summary>
        /// <returns></returns>
        public GACFFP.User GetCurrentUser(string sGACFFP_voterName)
        {
            return GetCurrentUser(sGACFFP_voterName, true);           
        }





        /// <summary>
        /// This method takes a string value as input and returns a user object
        /// This method also takes the boolean of setting the cookie or no.
        /// </summary>
        /// <returns></returns>
        public GACFFP.User GetCurrentUser(string sGACFFP_voterName, bool SetUserCookie)
        {
            string EncryptedUserName = GACFFP.Services.ValidateVoter.EncryptUser(sGACFFP_voterName);

            if (GACFFP.Services.ValidateVoter.IsValidFPUser(EncryptedUserName))
            {
                try
                {
                    if (SetUserCookie)
                    {
                        GACFFP.Services.ValidateVoter.AddGACFFPCookie(sGACFFP_voterName);
                    }

                    //get user by passing name into the onion username->userid->user
                    return GetUser(GetUserID(sGACFFP_voterName));

                }
                catch (Exception e)
                {
                    //TODO logging logic

                    return null;
                }


            }
            else //not a valid user
            {
                return null;
            }
        
        }



        public  DateTime GetMostRecentVoteDateByUser(string userName)
        {
            DateTime MostRecentVoteDate = new DateTime();

            try
            {
                List<MostRecentVoteByUser> returnMostRecentVote = fpE.GetMostRecentVoteByUserName(userName.Trim()).ToList();

                foreach (MostRecentVoteByUser m in returnMostRecentVote)
                {
                    MostRecentVoteDate = m.DATE;
                }

            }
            catch (Exception e)
            {
                //TODO logging logic
                return DateTime.Parse("10-10-1999");
            }

            return MostRecentVoteDate;
        }




        internal List<Role> GetRolesList()
        {
            GACFFP.FootballPollEntities fpE = new FootballPollEntities();

            return fpE.Roles.ToList();

        }





    }
}